home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / glimpse-2.1 / index / io.c < prev    next >
C/C++ Source or Header  |  1995-05-16  |  19KB  |  717 lines

  1. /* Copyright (c) 1994 Sun Wu, Udi Manber, Burra Gopal.  All Rights Reserved. */
  2. /* ./glimpse/index/io.c */
  3. #include "glimpse.h"
  4. #include <stdio.h>
  5. #include <sys/stat.h>
  6. extern char INDEX_DIR[MAX_LINE_LEN];
  7. extern int memory_usage;
  8.  
  9. /* --------------------------------------------------------------------
  10. get_array_of_lines()
  11. input: an input filename, address of the table, maximum number of entries
  12. of the table, and a overflow handling flag.
  13. output: a set of strings in the table.
  14. when overflow is ON, the function returns after the table is filled.
  15. otherwise the function will exit if overflow occurs.
  16. In normal return, the function returns the number of entries read.
  17. ----------------------------------------------------------------------*/
  18. get_array_of_lines(inputfile, table, max_entry, overflow_ok)
  19. char *inputfile;
  20. unsigned char *table[];
  21. int  max_entry;  /* max number of entries in the table */
  22. int  overflow_ok;   /* flag for handling overflow */
  23. {
  24.     int  tx=0;    /* index for table */
  25.     FILE *file_in;
  26.     unsigned char buffer[MAX_NAME_BUF];
  27.     char *np;     
  28.     int  line_length;
  29.  
  30.     if((file_in = fopen(inputfile, "r")) == NULL) {
  31.         if (overflow_ok) return 0;
  32.         fprintf(stderr, "can't open %s for reading\n", inputfile);
  33.         exit(3);
  34.     }
  35.  
  36.     while(fgets(buffer, MAX_NAME_BUF, file_in)) {
  37.         line_length = strlen(buffer);
  38.         buffer[line_length-1] = '\0';  /* discard the '\n' */
  39. #if    BG_DEBUG
  40.         np = (char *) my_malloc(sizeof(char) * (line_length + 2));
  41. #else    /*BG_DEBUG*/
  42.         np = (char *) my_malloc(sizeof(char) * (line_length + 2));
  43. #endif    /*BG_DEBUG*/
  44.         if(np == NULL) {
  45.             int    i=0;
  46.  
  47.             fclose(file_in);
  48.             for (i=0; i<tx; i++) {
  49. #if    BG_DEBUG
  50.             memory_usage -= (strlen(table[i]) + 2);
  51. #endif    /*BG_DEBUG*/
  52.             my_free(table[i], 0);
  53.             }
  54.             if (overflow_ok) {
  55.             fclose(file_in);
  56.             return 0;
  57.             }
  58.             fprintf(stderr, "malloc failure in get_array_of_lines\n");
  59.             exit(2);
  60.         }
  61.         table[tx++] = (unsigned char *)np;
  62.         strcpy(np, buffer);
  63.         if(tx > max_entry) {
  64.             fclose(file_in);
  65.             if(overflow_ok) {
  66.             return(tx);
  67.             }
  68.             fprintf(stderr, "overflow in get_array_of_lines()\n");
  69.             exit(2);
  70.         }
  71.     }
  72.     fclose(file_in);
  73.     return(tx);   /* return number of lines read */
  74. }
  75.  
  76. /* --------------------------------------------------------------------
  77. get_table():
  78. input: an input filename, address of the table, maximum number of entries
  79. of the table, and a overflow handling flag.
  80. output: a set of integers in the table.
  81. when overflow_ok is ON, the function returns after the table is filled.
  82. otherwise the function will exit if overflow occurs.
  83. In normal return, the function returns the number of entries read.
  84. ----------------------------------------------------------------------*/
  85. int get_table(inputfile, table, max_entry, overflow_ok)
  86. char *inputfile;
  87. int  table[];
  88. int  max_entry;
  89. int  overflow_ok;
  90. {
  91.     int  val = 0;
  92.     int  c = 0;
  93.     FILE *file_in;
  94.     int  tx=0;           /* number of entries read */
  95.  
  96.     if((file_in = fopen(inputfile, "r")) == NULL) {
  97.         if (overflow_ok) return 0;
  98.         fprintf(stderr, "can't open %s for reading\n", inputfile);
  99.         exit(2);
  100.     }
  101.     while((c = getc(file_in)) != EOF) {
  102.         val = c << 24;
  103.         if ((c = getc(file_in)) == EOF) break;
  104.         val |= c << 16;
  105.         if ((c = getc(file_in)) == EOF) break;
  106.         val |= c << 8;
  107.         if ((c = getc(file_in)) == EOF) break;
  108.         val |= c;
  109.  
  110.         table[tx++] = val;
  111.         if(tx > max_entry) {
  112.             if(!overflow_ok) {
  113.                 fprintf(stderr, "in get_table: table overflow\n");
  114.                 exit(2);
  115.             }
  116.             break;
  117.         }
  118.     }
  119.     fclose(file_in);
  120.     return(tx);
  121. }
  122.  
  123. get_index_type(s)
  124. char *s;
  125. {
  126.     FILE *fp = fopen(s, "r");
  127.     char buf[32];
  128.     int num;
  129.  
  130.     if (fp == NULL) return 0;
  131.     fscanf(fp, "%s\n%%%d\n", buf, &num);
  132.     /* buf is "%%" or "%%1234567890", num is >= 0 */
  133.     /* printf("get_index_type(): %s %d\n", buf, num); */
  134.     fclose(fp);
  135.     return num;
  136. }
  137.  
  138. /* n is guaranteed to be < MaxNum4bPartition */
  139.  
  140. int
  141. encode4b(n)
  142.     int    n;
  143. {
  144.     if (n=='\0') return MaxNum4bPartition;
  145.     if (n=='\n') return MaxNum4bPartition+1;
  146.     return n;
  147. }
  148.  
  149. int
  150. decode4b(n)
  151.     int n;
  152. {
  153.     if (n==MaxNum4bPartition) return '\0';
  154.     if (n==MaxNum4bPartition+1) return '\n';
  155.     return n;
  156. }
  157.  
  158. /* n is guaranteed to be < MaxNum8bPartition */
  159.  
  160. int
  161. encode8b(n)
  162.     int n;
  163. {
  164.     if (n=='\0') return MaxNum8bPartition;
  165.     if (n=='\n') return MaxNum8bPartition+1;
  166.     return n;
  167. }
  168.  
  169. int
  170. decode8b(n)
  171.     int n;
  172. {
  173.     if (n==MaxNum8bPartition) return '\0';
  174.     if (n==MaxNum8bPartition+1) return '\n';
  175.     return n;
  176. }
  177.  
  178. /* n is guaranteed to be < MaxNum12bPartition */
  179.  
  180. int
  181. encode12b(n)
  182.     int n;
  183. {
  184.     unsigned char msb, lsb;
  185.  
  186.     msb = (n / MaxNum8bPartition);
  187.     lsb = (n % MaxNum8bPartition);
  188.     msb = encode4b(msb);
  189.     lsb = encode8b(lsb);
  190.     return (msb<<8)|lsb;
  191. }
  192.  
  193. int
  194. decode12b(n)
  195.     int n;
  196. {
  197.     unsigned char msb, lsb;
  198.  
  199.     msb = ((n&0x00000f00) >> 8);
  200.     lsb = (n&0x000000ff);
  201.     msb = decode4b(msb);
  202.     lsb = decode8b(lsb);
  203.     return (msb * MaxNum8bPartition) + lsb;
  204. }
  205.  
  206. /* n is guaranteed to be < MaxNum16bPartition */
  207.  
  208. int
  209. encode16b(n)
  210.     int n;
  211. {
  212.     unsigned char msb, lsb;
  213.  
  214.     msb = (n / MaxNum8bPartition);
  215.     lsb = (n % MaxNum8bPartition);
  216.     msb = encode8b(msb);
  217.     lsb = encode8b(lsb);
  218.     return (msb<<8)|lsb;
  219. }
  220.  
  221. int
  222. decode16b(n)
  223.     int n;
  224. {
  225.     unsigned char msb, lsb;
  226.  
  227.     msb = ((n&0x0000ff00) >> 8);
  228.     lsb = (n&0x000000ff);
  229.     msb = decode8b(msb);
  230.     lsb = decode8b(lsb);
  231.     return (msb * MaxNum8bPartition) + lsb;
  232. }
  233.  
  234. /* n is guaranteed to be < MaxNum24bPartition */
  235.  
  236. int
  237. encode24b(n)
  238.     int n;
  239. {
  240.     unsigned short msb, lsb;
  241.  
  242.     msb = (n / MaxNum16bPartition);
  243.     lsb = (n % MaxNum16bPartition);
  244.     msb = encode8b(msb);
  245.     lsb = encode16b(lsb);
  246.     return (msb<<16)|lsb;
  247. }
  248.  
  249. int
  250. decode24b(n)
  251.     int n;
  252. {
  253.     unsigned short msb, lsb;
  254.  
  255.     msb = ((n&0x00ff0000) >> 16);
  256.     lsb = (n&0x0000ffff);
  257.     msb = decode8b(msb);
  258.     lsb = decode16b(lsb);
  259.     return (msb * MaxNum16bPartition) + lsb;
  260. }
  261.  
  262. /* n is guaranteed to be < MaxNum32bPartition */
  263.  
  264. int
  265. encode32b(n)
  266.     int n;
  267. {
  268.     unsigned short msb, lsb;
  269.  
  270.     msb = (n / MaxNum16bPartition);
  271.     lsb = (n % MaxNum16bPartition);
  272.     msb = encode16b(msb);
  273.     lsb = encode16b(lsb);
  274.     return (msb<<16)|lsb;
  275. }
  276.  
  277. int
  278. decode32b(n)
  279.     int n;
  280. {
  281.     unsigned short msb, lsb;
  282.  
  283.     msb = ((n&0xffff0000) >> 16);
  284.     lsb = (n&0x0000ffff);
  285.     msb = decode16b(msb);
  286.     lsb = decode16b(lsb);
  287.     return (msb * MaxNum16bPartition) + lsb;
  288. }
  289.  
  290. extern unsigned char dest_index_buf[REAL_INDEX_BUF];
  291. extern unsigned char src_index_buf[REAL_INDEX_BUF];
  292.  
  293. /* Read offset from srcbuf first so that you can use it with srcbuf=destbuf */
  294. get_block_numbers(srcbuf, destbuf, partfp)
  295.     unsigned char *srcbuf, *destbuf;
  296.     FILE *partfp;
  297. {
  298.     int    offset, pat_size;
  299.  
  300.     /* Does not do caching of blocks seen so far: done in OS hopefully */
  301.     offset = (srcbuf[0] << 24) |
  302.         (srcbuf[1] << 16) |
  303.         (srcbuf[2] << 8) |
  304.         (srcbuf[3]);
  305.     pat_size = decode32b(offset);
  306.  
  307.     fseek(partfp, pat_size, 0);
  308.     fgets(destbuf, REAL_INDEX_BUF, partfp);
  309. }
  310.  
  311. /* Merges the index split by save_data_structures into a single index */
  312. merge_splits()
  313. {
  314.     FILE *i_in;
  315.     FILE *p_in;
  316.     FILE *i_out;
  317.     char s[MAX_LINE_LEN];
  318.     int j, wordoffset, index;
  319.     unsigned char c;
  320.     char indexnumberbuf[256];
  321.     int onefileperblock, structuredindex;
  322.  
  323. #if    0
  324.     fflush(stdout);
  325.     printf("BEFORE MERGE_SPLITS:\n");
  326.     sprintf(s, "ls -lg .glimpse_*");
  327.     system(s);
  328.     getchar();
  329. #endif    /*0*/
  330.  
  331.     sprintf(s, "%s/%s", INDEX_DIR, P_TABLE);
  332.     if ((p_in = fopen(s, "r")) == NULL) {
  333.         fprintf(stderr, "cannot open for reading: %s\n", s);
  334.         exit(3);
  335.  
  336.     }
  337.     sprintf(s, "%s/%s", INDEX_DIR, INDEX_FILE);
  338.     if ((i_in = fopen(s, "r")) == NULL) {
  339.         fprintf(stderr, "cannot open for reading: %s\n", s);
  340.         exit(3);
  341.     }
  342.     sprintf(s, "%s/.glimpse_merge.%d", INDEX_DIR, getpid());
  343.     if ((i_out = fopen(s, "w")) == NULL) {
  344.         fprintf(stderr, "cannot open for writing: %s\n", s);
  345.         exit(3);
  346.     }
  347.  
  348.     /* modified the original in glimpse's main.c */
  349.     fgets(indexnumberbuf, 256, i_in);
  350.     fputs(indexnumberbuf, i_out);
  351.     fscanf(i_in, "%%%d\n", &onefileperblock);
  352.     fprintf(i_out, "%%%d\n", onefileperblock);
  353.     fscanf(i_in, "%%%d\n", &structuredindex);
  354.     if (structuredindex <= 0) structuredindex = 0;
  355.     fprintf(i_out, "%%%d\n", structuredindex);
  356.  
  357.     while (fgets(src_index_buf, REAL_INDEX_BUF, i_in)) {
  358.         if (structuredindex) {
  359.         if (structuredindex < MaxNum8bPartition - 1) wordoffset = j = 1;
  360.         else if (structuredindex < MaxNum16bPartition - 1) wordoffset = j = 2;
  361.         else wordoffset = j = 4;
  362.         }
  363.         else wordoffset = j = 0;
  364.  
  365.         while ((j < REAL_INDEX_BUF) && (src_index_buf[j] != WORD_END_MARK) && (src_index_buf[j] != ALL_INDEX_MARK) && (src_index_buf[j] != '\n')) j++;
  366.         if ((j >= REAL_INDEX_BUF) || (src_index_buf[j] == '\n')) continue;
  367.         /* else it is WORD_END_MARK or ALL_INDEX_MARK */
  368.         if (structuredindex) {    /* convert all types of stuff to 4B indices to make merge_in()s easy in build_in.c */
  369.         if (structuredindex < MaxNum8bPartition - 1) index = decode8b(src_index_buf[0]);
  370.         else if (structuredindex < MaxNum16bPartition - 1) index = decode16b((src_index_buf[0] << 8) | src_index_buf[1]);
  371.         else index = decode32b((src_index_buf[0] << 24) | (src_index_buf[1] << 16) | (src_index_buf[2] << 8) | (src_index_buf[3]));
  372.         index = encode32b(index);
  373.         putc((index & 0xff000000) >> 24, i_out);
  374.         putc((index & 0x00ff0000) >> 16, i_out);
  375.         putc((index & 0x0000ff00) >> 8, i_out);
  376.         putc(index & 0x000000ff, i_out);
  377.         }
  378.         c = src_index_buf[j+1];
  379.         src_index_buf[j+1] = '\0';
  380.         fputs(src_index_buf+wordoffset, i_out);
  381.         src_index_buf[j+1] = c;
  382.         if (src_index_buf[j] == ALL_INDEX_MARK) {
  383.         fputc(DONT_CONFUSE_SORT, i_out);
  384.         fputc('\n', i_out);
  385.         continue;
  386.         }
  387.  
  388.         get_block_numbers(&src_index_buf[j+1], dest_index_buf, p_in);
  389.         j=0;    /* first byte of the block numbers */
  390.         while(dest_index_buf[j] != '\n')
  391.         fputc(dest_index_buf[j++], i_out);
  392.         if (fputc('\n', i_out) == EOF) {
  393.         fprintf(stderr, "Error: write failed at %s:%d\n", __FILE__, __LINE__);
  394.         exit(2);
  395.         }
  396.     }
  397.  
  398.     fclose(i_in);
  399.     fclose(p_in);
  400.     fflush(i_out);
  401.     fclose(i_out);
  402.     sprintf(s, "mv %s/.glimpse_merge.%d %s/%s", INDEX_DIR, getpid(), INDEX_DIR, INDEX_FILE);
  403.     system(s);
  404.  
  405. #if    0
  406.     fflush(stdout);
  407.     printf("AFTER MERGE_SPLITS:\n");
  408.     sprintf(s, "ls -lg .glimpse_*");
  409.     system(s);
  410.     getchar();
  411. #endif    /*0*/
  412. }
  413.  
  414. /*
  415.  * converts file-names with *,. and ? and converts it to # \. and ? ALL OTHER agrep-special characters are masked off.
  416.  * if the filename NOT a regular expression involving ? or *, it leaves the name untouched and returns the string
  417.  * length of the file name (so that we can avoid memagrep calls): otherwise, it returns the -ve strlength of the name
  418.  * after performing the above conversion: hence we never need to call agrep if the length is +ve.
  419.  */
  420. convert2agrepregexp(buf, len)
  421.     char    *buf;
  422.     int    len;
  423. {
  424.     char    tbuf[MAX_PAT];
  425.     int    i=0, j=0;
  426.  
  427.     /* Ignore '*' at the beginning and '*' at the end */
  428.     if (len < 1) return 0;
  429.     if ( ((len == 1) && (buf[len-1] == '*')) || ((len >= 2) && (buf[len-1] == '*') && (buf[len-1] != '\\')) ) {
  430.         buf[len-1] = '\0';
  431.         len--;
  432.     }
  433.     if (buf[0] == '*') {
  434.         for (i=0; i<len; i++)
  435.             buf[i] = buf[i+1];
  436.         len--;
  437.     }
  438.     if (len < 1) {
  439.         buf[0] = '.';
  440.         buf[1] = '*';
  441.         buf[2] = '\0';
  442.         return -2;
  443.     }
  444.  
  445.     for (i=0; i<len; i++)
  446.         if (buf[i] == '\\') i++;
  447.         else if ((buf[i] == '?') || (buf[i] == '*')) break;
  448.     if (i >= len) return len;
  449.  
  450.     i = j = 0;
  451.     while ((i<len) && (j<MAX_PAT) && (buf[i] != '\0')) {
  452.         /* Consider all special characters interpreted by agrep */
  453.         if (buf[i] == '\\') {
  454.             /* copy two things without interpreting them */
  455.             tbuf[j++] = buf[i++];
  456.             tbuf[j++] = buf[i++];
  457.         }
  458.         else if ((buf[i] == '-') || (buf[i] == ',') || (buf[i] == ';')||
  459.              (buf[i] == '.') || (buf[i] == '#') || (buf[i] == '|')||
  460.              (buf[i] == '[') || (buf[i] == ']') || (buf[i] == '(')||
  461.              (buf[i] == ')') || (buf[i] == '>') || (buf[i] == '<')||
  462.              (buf[i] == '^') || (buf[i] == '$') || (buf[i] == '+')||
  463.              (buf[i] == '{') || (buf[i] == '}') || (buf[i] == '~')){
  464.             tbuf[j++] = '\\';
  465.             tbuf[j++] = buf[i];
  466.             i++;
  467.         }
  468.         /* Interpret ONLY ? and * in file-names */
  469.         else if (buf[i] == '?') {
  470.             tbuf[j++] = '.';
  471.             i++;
  472.         }
  473.         else if (buf[i] == '*') {
  474.             tbuf[j++] = '.';
  475.             tbuf[j++] = '*';
  476.             i++;
  477.         }
  478.         else tbuf[j++] = buf[i++];
  479.     }
  480.  
  481.     if (j >= MAX_PAT) {
  482.         tbuf[j-1] = '\0';
  483.         fprintf(stderr, "glimpseindex: pattern '%s' too long\n", buf);
  484.         j--;
  485.     }
  486.     else {
  487.         tbuf[j] = '\0';
  488.     }
  489.  
  490.     strcpy(buf, tbuf);
  491. #if    0
  492.     printf("%s=%d\n", buf, j);
  493. #endif    /*0*/
  494.     return -j;    /* strlen-compatible, -ve to indicate memagrep must be called */
  495. }
  496.  
  497. extern int num_filter;
  498. extern int filter_len[MAX_FILTER];
  499. extern CHAR *filter[MAX_FILTER];
  500. extern CHAR *filter_command[MAX_FILTER];
  501.  
  502. read_filters(index_dir, dofilter)
  503. char    *index_dir;
  504. int    dofilter;
  505. {
  506.     int len;
  507.     int patlen;
  508.     int patpos;
  509.     int commandpos;
  510.     FILE *filterfile;
  511.     char filterbuf[MAX_LINE_LEN];
  512.     char tempbuf[MAX_LINE_LEN];
  513.     char s[MAX_LINE_LEN];
  514.  
  515.     num_filter = 0;
  516.     memset(filter, '\0', sizeof(CHAR *) * MAX_FILTER);
  517.     memset(filter_command, '\0', sizeof(CHAR *) * MAX_FILTER);
  518.     memset(filter_len, '\0', sizeof(int) * MAX_FILTER);
  519.  
  520.     if (!dofilter) return;
  521.     sprintf(s, "%s/%s", index_dir, FILTER_FILE);
  522.     filterfile = fopen(s, "r");
  523.     if(filterfile == NULL) {
  524.     /* fprintf(stderr, "can't open filter file %s\n", s); -- no need */
  525.     num_filter = 0;
  526.     }
  527.     else {
  528.     while((num_filter < MAX_FILTER) && fgets(filterbuf, MAX_LINE_LEN, filterfile)) {
  529.         if ((len = strlen(filterbuf)) < 1) continue;
  530.         filterbuf[len-1] = '\0';
  531.         commandpos = 0;
  532.  
  533.         while ((commandpos < len) && ((filterbuf[commandpos] == ' ') || (filterbuf[commandpos] == '\t'))) commandpos ++;    /* leading spaces */
  534.         if (commandpos >= len) continue;
  535.         if (filterbuf[commandpos] == '\'') {
  536.             commandpos ++;
  537.             patpos = commandpos;
  538.             patlen = 0;
  539.             while (commandpos < len) {
  540.                 if (filterbuf[commandpos] == '\\') {
  541.                     commandpos += 2;
  542.                     patlen += 2;
  543.                 }
  544.                 else if (filterbuf[commandpos] != '\'') {
  545.                     commandpos ++;
  546.                     patlen ++;
  547.                 }
  548.                 else break;
  549.             }
  550.             if ((commandpos >= len) || (patlen <= 0)) continue;
  551.             commandpos ++;
  552.         }
  553.         else {
  554.             patpos = commandpos;
  555.             patlen = 0;
  556.             while ((commandpos < len) && (filterbuf[commandpos] != ' ') && (filterbuf[commandpos] != '\t')) {
  557.                 commandpos ++;
  558.                 patlen ++;
  559.             }
  560.             while ((commandpos < len) && ((filterbuf[commandpos] == ' ') || (filterbuf[commandpos] == '\t'))) commandpos ++;
  561.             if (commandpos >= len) continue;
  562.         }
  563.  
  564.         memcpy(tempbuf, &filterbuf[patpos], patlen);
  565.         tempbuf[patlen] = '\0';
  566.         if ((filter_len[num_filter] = convert2agrepregexp(tempbuf, patlen)) == 0) continue;    /* inplace conversion */
  567.         filter[num_filter] = (unsigned char *) strdup(tempbuf);
  568.         filter_command[num_filter] = (unsigned char *)strdup(&filterbuf[commandpos]);
  569.         num_filter ++;
  570.     }
  571.     fclose(filterfile);
  572.     }
  573. }
  574.  
  575. /* 1 if filter application was successful and the output (>1B) is in outname, 2 if some pattern matched but there is no output, 0 otherwise: sep 15-18 '94 */
  576. /* memagrep is initialized in partition.c for calls from dir.c, and it is already done by the time we call this function from main.c */
  577. apply_filter(inname, outname)
  578.     char    *inname, *outname;    /* outname is in-out, inname is in */
  579. {
  580.     int    i;
  581.     char    name[MAX_LINE_LEN];
  582.     int    name_len = strlen(inname);
  583.     char    s[MAX_LINE_LEN];
  584.     FILE    *dummyout;
  585.     FILE    *dummyin;
  586.     char    dummybuf[4];
  587.     char    prevoutname[MAX_LINE_LEN];
  588.     char    newoutname[MAX_LINE_LEN];
  589.     int    ret = 0;
  590.     int    unlink_prevoutname = 0;
  591.  
  592.     if (num_filter <= 0) return 0;
  593.     if ((dummyout = fopen("/dev/null", "w")) == NULL) return 0;
  594.     /* ready for memgrep */
  595.     name[0] = '\n';
  596.     strcpy(name+1, inname);
  597.     strcpy(prevoutname, inname);
  598.     strcpy(newoutname, outname);
  599.  
  600.     /* Current properly filtered output is always in prevoutname */
  601.     for(i=0; i<num_filter; i++) {
  602.         if (filter_len[i] > 0) {
  603.             char *suffix;
  604.             name[name_len + 1] = '\0';
  605.             /* if (strstr(name+1, filter[i]) != NULL) { Chris Dalton */
  606.             if ((suffix = strstr(name+1, filter[i])) != NULL) {
  607.                 if (ret == 0) ret = 2;
  608.                 /* yes, it matched: now apply the command and get the output */
  609.                 /* printf("filtering %s\n", name); */
  610.                 sprintf(s, "%s '%s' > %s", filter_command[i], prevoutname, newoutname);
  611.                 system(s);
  612.                 if (((dummyin = fopen(newoutname, "r")) == NULL) || (fread(dummybuf, 1, 1, dummyin) <= 0)) {
  613.                     if (dummyin != NULL) fclose(dummyin);
  614.                     unlink(newoutname);
  615.                     continue;
  616.                 }
  617.                 /* Filter was successful: output exists and has atleast 1 byte in it */
  618.                 fclose(dummyin);
  619.                 if (unlink_prevoutname) unlink(prevoutname);
  620.                 strcpy(prevoutname, newoutname);
  621.                 sprintf(newoutname, "%s.o", prevoutname);
  622.                 ret = 1;
  623.                 unlink_prevoutname = 1;
  624. #if    1
  625.                 /* if the matched text was a proper suffix of the name, */
  626.                 /* remove the suffix just processed before examining the */
  627.                 /* name again. Chris Dalton */
  628.                 /* And I don't know what the equivalent thing is with */
  629.                 /* memagrep_search: since it doesn't return a pointer to */
  630.                 /* the place where the match occured. Burra Gopal */
  631.                 if (strcmp(filter[i], suffix) == 0) {
  632.                     name_len -= strlen(suffix);
  633.                     *suffix= '\0';
  634.                 }
  635. #endif    /*1*/
  636.                 if (strlen(newoutname) >= MAX_LINE_LEN - 1) break;
  637.             }
  638.         }
  639.         else {    /* must call memagrep */
  640.             name[name_len + 1] = '\n';    /* memagrep wants names to end with '\n': '\0' is not necessary */
  641.             /* printf("i=%d filterlen=%d filter=%s inlen=%d input=%s\n", i, -filter_len[i], filter[i], len_current_dir_buf, current_dir_buf); */
  642.             if (((filter_len[i] == -2) && (filter[i][0] == '.') && (filter[i][1] == '*')) ||
  643.                 (memagrep_search(-filter_len[i], filter[i], name_len + 2, name, 0, dummyout) > 0)) {
  644.                 if (ret == 0) ret = 2;
  645.                 /* yes, it matched: now apply the command and get the output */
  646.                 /* printf("filtering %s\n", name); */
  647.                 sprintf(s, "%s '%s' > %s", filter_command[i], prevoutname, newoutname);
  648.                 system(s);
  649.                 if (((dummyin = fopen(newoutname, "r")) == NULL) || (fread(dummybuf, 1, 1, dummyin) <= 0)) {
  650.                     if (dummyin != NULL) fclose(dummyin);
  651.                     unlink(newoutname);
  652.                     continue;
  653.                 }
  654.                 /* Filter was successful: output exists and has atleast 1 byte in it */
  655.                 fclose(dummyin);
  656.                 if (unlink_prevoutname) unlink(prevoutname);
  657.                 strcpy(prevoutname, newoutname);
  658.                 sprintf(newoutname, "%s.o", prevoutname);
  659.                   ret = 1;
  660.                 unlink_prevoutname = 1;
  661.                 if (strlen(newoutname) >= MAX_LINE_LEN - 1) break;
  662.             }
  663.         }
  664.     }
  665.     if (ret == 1) strcpy(outname, prevoutname);
  666.     else {    /* dummy filter that copies input to output: caller can use inname but this has easy interface */
  667.         sprintf(s, "cat %s > %s\n", inname, outname);
  668.         system(s);
  669.     }
  670.     fclose(dummyout);
  671.     return ret;
  672. }
  673.  
  674. /* Use a modified wais stoplist to do this with simple strcmp's in a for loop */
  675. static_stop_list(word)
  676.     char    *word;
  677. {
  678.     return 0;
  679. }
  680.  
  681. /* crazy hash function that operates on 4K hashtables: bug fixes by Chris Dalton */
  682. hash4k(word, len)
  683.     char     *word;
  684.     int    len;
  685. {
  686.     unsigned int hash_value=0;
  687.     unsigned int mask_3=07;
  688.     unsigned int mask_12=07777;
  689.     int i;
  690.  
  691. #if    0
  692.     /* discard prefix = the directory name */
  693.     if (len<=1) return 0;
  694.     i = len-1;
  695.     while(word[i] != '/') i--;
  696.     if ((i > 0) && (word[i] == '/')) {
  697.     word = &word[i+1];
  698.     len = strlen(word);
  699.     }
  700. #endif    /*0*/
  701.  
  702.     if(len<=4) {
  703.     for(i=0; i<len; i++) {
  704.                hash_value = (hash_value << 3) | (word[i]&mask_3);
  705.     }
  706.     }
  707.     else {
  708.     for(i=0; i<4; i++) {
  709.                hash_value = (hash_value << 3) | (word[i]&mask_3);
  710.     }
  711.     for(i=4; i<len; i++) 
  712.         hash_value = mask_12 & (hash_value + word[i]);
  713.     }
  714.     return(hash_value & mask_12);
  715. }
  716.  
  717.